package com.bwie.shop.service.impl;

import cn.hutool.core.date.DateUtil;
import com.bwie.common.constants.TokenConstants;
import com.bwie.common.domain.Shop;
import com.bwie.common.domain.ShopContract;
import com.bwie.common.domain.request.AddContractRequest;
import com.bwie.common.domain.request.AddShopRequest;
import com.bwie.common.domain.request.ShopContractRequest;
import com.bwie.common.domain.request.ShopRequest;
import com.bwie.common.domain.response.JwtResponse;
import com.bwie.common.domain.response.ShopContractResponse;
import com.bwie.common.domain.response.ShopResponse;
import com.bwie.common.domain.response.UserInfo;
import com.bwie.common.exctption.BizException;
import com.bwie.common.utils.JwtUtils;
import com.bwie.common.utils.StringUtils;
import com.bwie.shop.mapper.ShopMapper;
import com.bwie.shop.service.ShopService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.http.HttpServletRequest;
import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
import java.util.concurrent.TimeUnit;

/**
 * 店铺业务处理层
 *
 * @author <a href="mailto:2891704036@qq.com">zhiyuheng</a>
 * @version 1.0
 * @description: 店铺业务处理层
 * @date 2025/9/9 10:36
 */
@Service
public class ShopServiceImpl implements ShopService {

    @Autowired
    private ShopMapper shopMapper;
    @Autowired
    private RedisTemplate redisTemplate;
    @Autowired
    private HttpServletRequest request;

    /**
     * 店铺列表
     * @param shopRequest
     * @return
     */
    @Override
    public List<ShopResponse> shopList(ShopRequest shopRequest) {
        //获取请求头中的token
        String token = request.getHeader(TokenConstants.TOKEN);
        //获取用户标识
        String userKey = JwtUtils.getUserKey(token);
        //从redis中获取登录存储的用户信息
        UserInfo userInfo = (UserInfo) redisTemplate.opsForValue().get(TokenConstants.LOGIN_TOKEN_KEY + userKey);
        //获取登录人ID
        Long userId = userInfo.getId();
        //获取登录人角色ID
        Long roleId = userInfo.getRoleId();

        //设置用户ID为当前登录人ID
        shopRequest.setUserId(userId);
        //设置角色ID为当前登录人角色ID
        shopRequest.setRoleId(roleId);

        return shopMapper.shopList(shopRequest);
    }

    /**
     * 店铺入驻
     * @param addShopRequest
     */
    @Override
    @Transactional
    public void addShop(AddShopRequest addShopRequest) {
        //获取请求头中的token
        String token = request.getHeader(TokenConstants.TOKEN);
        //获取用户标识
        String userKey = JwtUtils.getUserKey(token);
        //从redis中获取登录存储的用户信息
        UserInfo userInfo = (UserInfo) redisTemplate.opsForValue().get(TokenConstants.LOGIN_TOKEN_KEY + userKey);
        //获取用户余额
        BigDecimal balance = userInfo.getBalance();

        //缴纳保证金，先判断用户余额是否充足
        if (balance.compareTo(BigDecimal.valueOf(200)) <0 ){
            throw new BizException("用户余额不足，无法缴纳保证金！");
        }
        //如果余额足够，先扣除用户余额
        shopMapper.deductBalance(userInfo.getId());
        //再缴纳保证金
        addShopRequest.setMarginDeposit(BigDecimal.valueOf(200));
        //更新redis中用户的缓存
        UserInfo newUserInfo = shopMapper.findById(userInfo.getId());
        //重新存redis，因为余额有变动，所以需要重新查询并添加
        redisTemplate.opsForValue().set(TokenConstants.LOGIN_TOKEN_KEY + userKey, newUserInfo, 30, TimeUnit.MINUTES);

        //店铺名称唯一性校验，先查询数据库，是否有该商铺名
        String shopName = shopMapper.selectShopName(addShopRequest.getShopName());
        //如果不为空，则违背唯一性原则，不能新增
        if (StringUtils.isNotBlank(shopName)){
            throw new BizException("该商品名称已存在，请重新输入！");
        }

        //获取结束时间
        Date endTime = addShopRequest.getEndTime();
        //获取开始时间
        Date startTime = addShopRequest.getStartTime();
        //判断结束时间不能早于开始时间
        if (endTime.compareTo(startTime) <0 ){
            throw new BizException("结束时间不得早于开始时间");
        }

        //店铺状态默认正常
        addShopRequest.setStatus(0);
        //店铺负责人默认当前登录人
        addShopRequest.setUserId(userInfo.getId());
        //店铺录入时间默认为当前时间
        addShopRequest.setShopEntryTime(new Date());
        //合同数量默认为1
        addShopRequest.setContractQuantity(1);

        //店铺入驻
        shopMapper.addShop(addShopRequest);
        //添加店铺合同表
        shopMapper.addShopContract(addShopRequest);
    }

    /**
     * 审核通过
     * @param id
     */
    @Override
    public void reviewPass(Long id) {
        //获取请求头中的token
        String token = request.getHeader(TokenConstants.TOKEN);
        //获取用户标识
        String userKey = JwtUtils.getUserKey(token);
        //从redis中获取登录存储的用户信息
        UserInfo userInfo = (UserInfo) redisTemplate.opsForValue().get(TokenConstants.LOGIN_TOKEN_KEY + userKey);
        //获取登录用户的角色
        Long roleId = userInfo.getRoleId();

        //判断是否是管理员
        if (roleId != 1){
            throw new BizException("请联系管理员进行操作！");
        }

        //审核通过
        shopMapper.reviewPass(id);
    }

    /**
     * 审核驳回
     * @param id
     */
    @Override
    public void reviewReject(Long id) {
        //获取请求头中的token
        String token = request.getHeader(TokenConstants.TOKEN);
        //获取用户标识
        String userKey = JwtUtils.getUserKey(token);
        //从redis中获取登录存储的用户信息
        UserInfo userInfo = (UserInfo) redisTemplate.opsForValue().get(TokenConstants.LOGIN_TOKEN_KEY + userKey);
        //获取登录用户的角色
        Long roleId = userInfo.getRoleId();

        //判断是否是管理员
        if (roleId != 1){
            throw new BizException("请联系管理员进行操作！");
        }

        //审核驳回
        shopMapper.reviewReject(id);
    }

    /**
     * 店铺合同列表
     * @return
     */
    @Override
    public List<ShopContractResponse> shopContractList() {
        //获取请求头中的token
        String token = request.getHeader(TokenConstants.TOKEN);
        //获取用户标识
        String userKey = JwtUtils.getUserKey(token);
        //从redis中获取登录存储的用户信息
        UserInfo userInfo = (UserInfo) redisTemplate.opsForValue().get(TokenConstants.LOGIN_TOKEN_KEY + userKey);
        //new一个ShopContractRequest用来存放参数
        ShopContractRequest shopContractRequest = new ShopContractRequest();
        //设置角色ID和用户ID
        shopContractRequest.setUserId(userInfo.getId());
        shopContractRequest.setRoleId(userInfo.getRoleId());
        return shopMapper.shopContractList(shopContractRequest);
    }

    /**
     * 合同续约
     * @param request
     */
    @Override
    @Transactional
    public void addContract(AddContractRequest request) {
        //判断合同是否3个月以内到期，先获取合同的到期时间
        Date endTime = shopMapper.selectEndTime(request.getShopId());
        //获取当前时间的毫秒值
        Date date = new Date();
        long nowTime = date.getTime();
        //获取结束时间的毫秒值
        long doneTime = endTime.getTime();
        //获取3个月的毫秒值
        long oneDay = 60 * 60 * 24 * 1000;
        long threeMonth = oneDay * 90;
        //用结束时间减去当前时间后的毫秒值与三个月的毫秒值比较
        if ((doneTime - nowTime) < threeMonth){
            throw new BizException("店铺到期前3个月，才可以签订新合同！");
        }

        //获取开始时间
        Date startTime = request.getStartTime();
        //获取结束时间
        Date endTime1 = request.getEndTime();
        //判断结束时间不得早于开始时间
        if (endTime1.compareTo(startTime) <0 ){
            throw new BizException("结束时间不得早于开始时间");
        }

        //状态默认待审核
        request.setStatus(1);

        //合同数量加一
        shopMapper.updateContractQuantity(request.getShopId());

        //新增合同
        shopMapper.addContract(request);
    }

    /**
     * 店铺下拉框
     * @return
     */
    @Override
    public List<Shop> selectShop() {
        //获取请求头中的token
        String token = request.getHeader(TokenConstants.TOKEN);
        //获取用户标识
        String userKey = JwtUtils.getUserKey(token);
        //从redis中获取登录存储的用户信息
        UserInfo userInfo = (UserInfo) redisTemplate.opsForValue().get(TokenConstants.LOGIN_TOKEN_KEY + userKey);
        return shopMapper.selectShop(userInfo.getId());
    }

    /**
     * 合同审核通过
     * @param id
     */
    @Override
    public void reviewContractPass(Long id) {
        //获取请求头中的token
        String token = request.getHeader(TokenConstants.TOKEN);
        //获取用户标识
        String userKey = JwtUtils.getUserKey(token);
        //从redis中获取登录存储的用户信息
        UserInfo userInfo = (UserInfo) redisTemplate.opsForValue().get(TokenConstants.LOGIN_TOKEN_KEY + userKey);

        //判断是否是管理员
        if (userInfo.getRoleId() != 1){
            throw new BizException("请联系管理员进行操作");
        }

        //合同审核通过
        shopMapper.reviewContractPass(id);
    }

    /**
     * 合同审核驳回
     * @param id
     */
    @Override
    public void reviewContractReject(Long id) {
        //获取请求头中的token
        String token = request.getHeader(TokenConstants.TOKEN);
        //获取用户标识
        String userKey = JwtUtils.getUserKey(token);
        //从redis中获取登录存储的用户信息
        UserInfo userInfo = (UserInfo) redisTemplate.opsForValue().get(TokenConstants.LOGIN_TOKEN_KEY + userKey);

        //判断是否是管理员
        if (userInfo.getRoleId() != 1){
            throw new BizException("请联系管理员进行操作");
        }

        //合同审核驳回
        shopMapper.reviewContractReject(id);
    }

}
